package com.party.admin.biz.distribution;

import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.party.admin.web.dto.input.common.CommonQuery;
import com.party.admin.web.dto.input.distribution.ChildListInput;
import com.party.admin.web.dto.input.distribution.DistributionListInput;
import com.party.admin.web.dto.output.distribution.ChildListOutput;
import com.party.admin.web.dto.output.distribution.DistributionListOutput;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.common.utils.LangUtils;
import com.party.core.model.activity.Activity;
import com.party.core.model.crowdfund.ProjectWithAuthor;
import com.party.core.model.crowdfund.Support;
import com.party.core.model.crowdfund.SupportWithMember;
import com.party.core.model.distributor.*;
import com.party.core.model.mall.MallGoods;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.order.OrderForm;
import com.party.core.model.order.OrderStatus;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.copartner.IBrokerageItemService;
import com.party.core.service.crowdfund.IProjectService;
import com.party.core.service.crowdfund.ISupportService;
import com.party.core.service.distributor.IDistributorCountService;
import com.party.core.service.distributor.IDistributorDetailService;
import com.party.core.service.distributor.IDistributorRelationService;
import com.party.core.service.distributor.IDistributorTargetAttacheService;
import com.party.core.service.mall.IMallGoodsService;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.order.IOrderFormService;
import com.sun.istack.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 分销业务接口
 * Created by wei.li
 *
 * @date 2017/3/9 0009
 * @time 14:08
 */

@Service
public class DistributionBizService {

    @Autowired
    private IDistributorRelationService distributorRelationService;

    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberGroupService memberGroupService;

    @Autowired
    private IMallGoodsService mallGoodsService;

    @Autowired
    private IDistributorCountService distributorCountService;
    @Autowired
    private IDistributorDetailService distributorDetailService;
    @Autowired
    private IDistributorTargetAttacheService distributorTargetAttacheService;
    @Autowired
    private ISupportService supportService;
    @Autowired
    private IOrderFormService orderFormService;
    @Autowired
    private IBrokerageItemService brokerageItemService;
    @Autowired
    private IActivityService activityService;
    @Autowired
    private IProjectService projectService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 分销列表
     *
     * @param input 分销关系
     * @param page 分页参数
     * @return 分销关系列表
     */
    public List<DistributionListOutput> list(DistributionListInput input, Page page){
        String startTime = null;
        String endTime = null;
        if (input.getTimeType() != null && input.getTimeType() != 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            Date ed = calendar.getTime(); // 结束时间
            if (input.getTimeType() == 2) { // 本周内
                int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
                if (day_of_week == 0) {
                    day_of_week = 7;
                }
                calendar.add(Calendar.DATE, -day_of_week + 1);
            } else if (input.getTimeType() == 3) { // 本月内
                calendar.set(Calendar.DAY_OF_MONTH, 1);
            } else if (input.getTimeType() == 4) { // 昨天
                calendar.add(Calendar.DATE, -1);
                ed = calendar.getTime();
            }
            Date sd = calendar.getTime(); // 开始时间
            String std = sdf.format(sd) + " 00:00:00";
            startTime =  std;
            String end = sdf.format(ed) + " 23:59:59";
            endTime = end;
        }

        /*startTime = Strings.isNullOrEmpty(input.getStartDate()) ? startTime : input.getStartDate();
        endTime = Strings.isNullOrEmpty(input.getEndDate()) ? endTime : input.getEndDate();*/

        if (null != startTime) {
            input.setStartDate(startTime.substring(0, "2018-05-04".length()));
        }
        if (null != endTime) {
            input.setEndDate(endTime.substring(0, "2018-05-04".length()));
        }

        List<WithCount> withCountList
                = distributorRelationService.listWithCount(input.getType(), input.getTitle(),
                input.getDistributorName(), startTime, endTime, page);

        List<DistributionListOutput> listOutputs
                = LangUtils.transform(withCountList, new Function<WithCount, DistributionListOutput>() {
            @Override
            public DistributionListOutput apply(WithCount withCount) {
                DistributionListOutput distributionListOutput = DistributionListOutput.transform(withCount);
                MemberGroup member = memberGroupService.get(withCount.getParentId());
                if (member != null) {
                	distributionListOutput.setParentName(member.getRealname());
				}

                Member distributor = memberService.get(withCount.getDistributorId());
                distributionListOutput.setDistributorName(distributor.getRealname());
                distributionListOutput.setDistributorLogo(distributor.getLogo());
                return distributionListOutput;
            }
        });
        return listOutputs;
    }


    /**
     * 根据目标查询分销关系
     *
     * @param targetId 目标编号
     * @param input 输入视图
     * @param page 分页参数
     * @return 分销列表
     */
    public List<DistributionListOutput> targetList(String targetId,
                                                   DistributionListInput input, Page page){
        String startTime = input.getStartDate();
        String endTime = input.getEndDate();
        if (null != input.getTimeType() && !new Integer(0).equals(input.getTimeType())) {
            CommonQuery commonQuery = new CommonQuery();
            commonQuery.setTimeType(input.getTimeType());
            startTime = commonQuery.getCreateStart();
            endTime = commonQuery.getCreateEnd();
        }

        List<WithCount> withCountList
                = distributorRelationService.listWithCount(targetId, input.getTitle(),
                input.getType(), startTime, endTime,  page);

        List<DistributionListOutput> listOutputs
                = LangUtils.transform(withCountList, new Function<WithCount, DistributionListOutput>() {
            @Override
            public DistributionListOutput apply(WithCount withCount) {
                DistributionListOutput distributionListOutput = DistributionListOutput.transform(withCount);
                MemberGroup member = memberGroupService.get(withCount.getParentId());
                if (null != member) {
                    distributionListOutput.setParentName(member.getRealname());
                }

                Member distributor = memberService.get(withCount.getDistributorId());
                distributionListOutput.setDistributorName(distributor.getRealname());
                distributionListOutput.setDistributorLogo(distributor.getLogo());
                distributionListOutput.setTypeValue(DistributorRelationType.getValue(withCount.getType()));
                return distributionListOutput;
            }
        });
        return listOutputs;
    }


    /**
     * 子级分销列表
     *
     * @param distributionId 分销编号
     * @param input 输入视图
     * @param page 分页参数
     * @return 子级分销列表
     */
    public List<ChildListOutput> childList(String distributionId, ChildListInput input, Page page){
        String startTime = input.getStartDate();
        String endTime = input.getEndDate();
        if (null != input.getTimeType() && !new Integer(0).equals(input.getTimeType())) {
            CommonQuery commonQuery = new CommonQuery();
            commonQuery.setTimeType(input.getTimeType());
            startTime = commonQuery.getCreateStart();
            endTime = commonQuery.getCreateEnd();
        }

        //查询本级分销信息
        DistributorRelation distributorRelation = distributorRelationService.get(distributionId);

        //下级分销商
        List<WithCount> list = distributorRelationService.findByParentId(distributorRelation.getDistributorId(),
                distributorRelation.getTargetId(), input.getTitle(),
                input.getDistributorName(), input.getType(), startTime, endTime, page);
        List<ChildListOutput> childList = LangUtils.transform(list, new Function<WithCount, ChildListOutput>() {
            @Override
            public ChildListOutput apply(WithCount withCount) {
                ChildListOutput childListOutput = ChildListOutput.transform(withCount);
                Member member = memberService.get(withCount.getDistributorId());
                childListOutput.setDistributorName(member.getRealname());
                childListOutput.setDistributorLogo(member.getLogo());
                return childListOutput;
            }
        });
        return childList;
    }

    /**
     * 保存商品的分销关系
     *
     * @param orgId    机构id
     * @param goodsIds 商品id
     */
    public boolean saveShowGoodsDistributionBiz(String orgId, List<String> goodsIds) {
        for (String goodsId : goodsIds) {
            MallGoods mallGoods = mallGoodsService.get(goodsId);
            if (mallGoods == null) {
                continue;
            }
            DistributorRelation relation = distributorRelationService.get(DistributorRelationType.MALL_GOODS.getCode(), goodsId, orgId);
            if (relation == null) {
                relation = new DistributorRelation();
                relation.setType(DistributorRelationType.MALL_GOODS.getCode()); // 分销类型
                relation.setTargetId(goodsId); // 分销对象
                relation.setDistributorId(orgId); // 分销者
                relation.setParentId(mallGoods.getMemberId()); // 被分销者
                relation.setTargetEndDate(DateUtils.addYear(DateUtils.getTodayDate(), 1)); // 结束时间
                relation.setTitle(mallGoods.getName());
                relation.setPic(mallGoods.getPic());
                if (mallGoods.getPrice().indexOf("~") != -1) {
                    String[] prices = mallGoods.getPrice().split("~");
                    relation.setPrice(Float.valueOf(prices[0]));
                } else {
                    relation.setPrice(Float.valueOf(mallGoods.getPrice()));
                }
                distributorRelationService.insert(relation);
                return true;
            }
        }
        return false;
    }

    /**
     * 删除商城商品的分销关系
     *
     * @param orgId    机构id
     * @param goodsIds 商品id
     */
    public void deleteShowGoodsDistributionBiz(String orgId, List<String> goodsIds) {
        for (String goodsId : goodsIds) {
            DistributorRelation relation = new DistributorRelation();
            relation.setType(DistributorRelationType.MALL_GOODS.getCode());
            relation.setDistributorId(orgId);
            relation.setTargetId(goodsId);
            List<DistributorRelation> relations = distributorRelationService.listPage(relation, null);
            for (DistributorRelation dr : relations) {
                distributorRelationService.delete(dr.getId());
            }
        }
    }

    /**
     * 删除分销关系
     *
     * @param targetId      目标编号
     * @param distributorId 分销者编号
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteDistributionBiz(String targetId, String distributorId) {
        List<DistributorRelation> distributorRelations = distributorRelationService.findByTargetId(targetId, distributorId);
        distributorRelations.forEach(new Consumer<DistributorRelation>() {
            @Override
            public void accept(DistributorRelation distributorRelation) {
                distributorCountService.deleteByRelationId(distributorRelation.getId());
                distributorDetailService.deleteByRelationId(distributorRelation.getId());
                distributorTargetAttacheService.deleteByRelationId(distributorRelation.getId());
                distributorRelationService.delete(distributorRelation.getId());
            }
        });
    }

    public void doDuplicate() {
        List<String> targetIds = distributorDetailService.getDuplicateRecord();
        for (String targetId : targetIds) {
            try {
                DistributorDetail detail = new DistributorDetail();
                detail.setTargetId(targetId);
                detail.setType(DistributorDetailType.DISTRIBUTOR_TYPE_SUPPORT.getCode());
                List<DistributorDetail> distributorDetails = distributorDetailService.list(detail);
                List<String> relationIds = LangUtils.transform(distributorDetails, input -> input.getDistributorRelationId());
                if (relationIds.size() > 1) {
                    // 说明有一个支持订单对应多条众筹代言的分销关系，要删除一条错误的
                    Support support = supportService.findByOrderId(targetId);
                    // 众筹的分销详情
                    DistributorDetail projectDetail = distributorDetailService.findByTargetId(support.getProjectId());
                    relationIds.remove(projectDetail.getDistributorRelationId());

                    for (int i = 0; i < relationIds.size(); i++) {
                        DistributorDetail supportDetail = distributorDetailService.get(targetId, DistributorDetailType.DISTRIBUTOR_TYPE_SUPPORT.getCode(), relationIds.get(i));
                        if (null != supportDetail) {
                            distributorDetailService.delete(supportDetail.getId());
                        }
                    }
                }
            } catch (Exception e) {
                continue;
            }
        }
    }

    public Map<String, Object> getDisData(String relationId) {
        DistributorRelation distributorRelation = distributorRelationService.get(relationId);
        Map<String, Object> dataMap = Maps.newHashMap();
        DistributorCount distributorCount = distributorCountService.findByRelationId(relationId);
        dataMap.put("crowdfundNum", distributorCount.getCrowdfundNum());
        dataMap.put("totalMoney", distributorCount.getFavorerAmount());
        Double refundMoney = orderFormService.getDisMoney(relationId, OrderStatus.ORDER_STATUS_REFUND.getCode());
        Double remainMoney = BigDecimalUtils.sub(distributorCount.getFavorerAmount(), refundMoney);
        remainMoney = BigDecimalUtils.round(remainMoney, 2);
        dataMap.put("refundMoney", refundMoney);
        dataMap.put("remainMoney", remainMoney);
        dataMap.put("totalBrokerage", brokerageItemService.getDisBrokerage(distributorRelation.getDistributorId(), distributorRelation.getTargetId()));
        Member member = memberService.get(distributorRelation.getDistributorId());
        dataMap.put("name", member.getRealname());
        Activity activity = activityService.get(distributorRelation.getTargetId());
        dataMap.put("title", activity.getTitle());
        dataMap.put("parentId", distributorRelation.getDistributorId());
        return dataMap;
    }

    @Transactional
    public String activityApplyRefund(String targetId, OrderForm orderForm) {
        DistributorDetail applyDetail = distributorDetailService.findByTargetId(targetId);
        if (null != applyDetail) {
            try {
                DistributorCount distributorCount = distributorCountService.findByRelationId(applyDetail.getDistributorRelationId());
                if (null != distributorCount) {
                    distributorCount.setApplyNum(distributorCount.getApplyNum() - 1);

                    if (null != orderForm) {
                        float sub = BigDecimalUtils.sub(distributorCount.getFavorerAmount(), orderForm.getPayment());
                        sub = BigDecimalUtils.round(sub, 2);
                        distributorCount.setFavorerAmount(sub);

                        DistributorDetail orderDetail = distributorDetailService.findByTargetId(orderForm.getId());
                        distributorDetailService.delete(orderDetail.getId());
                    }

                    if (distributorCount.getApplyNum() < 0) {
                        distributorCount.setApplyNum(0);
                    }
                    if (distributorCount.getFavorerAmount() < 0) {
                        distributorCount.setFavorerAmount(0f);
                    }
                    distributorCountService.update(distributorCount);
                }
                distributorDetailService.delete(applyDetail.getId());
            } catch (Exception e) {
                logger.error("活动/课程退款后，分销数据处理异常", e);
            }
            return applyDetail.getDistributorRelationId();
        }
        return null;
    }

    /**
     * 根据目标编号找分销者编号
     *
     * @param targetId 目标编号
     * @return 分销者编号
     */
    public DistributorRelation getDistributorRelation(String targetId) {
        DistributorDetail distributorDetail = distributorDetailService.findByTargetId(targetId);
        if (distributorDetail != null) {
            DistributorRelation distributorRelation = distributorRelationService.get(distributorDetail.getDistributorRelationId());
            return distributorRelation;
        }
        return null;
    }

    /**
     * 刷新当前统计
     * @param distributorCount 分销统计
     * @param distributionType 分销类型
     */
    @Transactional
    public void refreshCount(DistributorCount distributorCount, Integer distributionType){

        //下级分销量
        DistributorRelation distributorRelation = distributorRelationService.get(distributorCount.getDistributorRalationId());
        if (null != distributorRelation){
            List<WithCount> withCountList = distributorRelationService.findByParentId(distributorRelation.getDistributorId(), distributorRelation.getTargetId());
            distributorCount.setShareNum(withCountList.size());
        }

        //报名量
        List<DistributorDetail> applyList = distributorDetailService.applyList(distributorCount.getDistributorRalationId());
        distributorCount.setApplyNum(applyList.size());

        //下单量
        List<DistributorDetail> buyList = distributorDetailService.buyList(distributorCount.getDistributorRalationId());
        distributorCount.setSalesNum(buyList.size());

        if (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributionType)
                || DistributorRelationType.CROWDFUND_REPRESENT.getCode().equals(distributionType)) {
            this.reviseCrowdfund(distributorCount, distributionType);
        }

        distributorCount.setUpdateDate(new Date());
        distributorCountService.update(distributorCount);
    }

    /**
     * 校正众筹数据
     * @param distributorCount 分销统计
     * @param distributionType 分销类型
     */
    @Transactional
    public void reviseCrowdfund(DistributorCount distributorCount, Integer distributionType){

        ProjectWithAuthor projectWithAuthor = new ProjectWithAuthor();
        projectWithAuthor.setRelationId(distributorCount.getDistributorRalationId());
        List<ProjectWithAuthor> projectWithAuthorList = projectService.listPage(projectWithAuthor, null);



        List<String> projectIds = LangUtils.transform(projectWithAuthorList, new Function<ProjectWithAuthor, String>() {
            @Nullable
            @Override
            public String apply(@Nullable ProjectWithAuthor projectWithAuthor) {
                if (null == projectWithAuthor){
                    return null;
                }
                return projectWithAuthor.getId();
            }
        });


        distributorCount.setCrowdfundNum(projectIds.size());

        if (projectIds != null && projectIds.size() > 0){
            List<SupportWithMember> crowdSupportList = supportService.findByProjectIds(Sets.newHashSet(projectIds));
            List<String> crowdSuppIds = LangUtils.transform(crowdSupportList, new Function<Support, String>() {
                @Nullable
                @Override
                public String apply(@Nullable Support input) {
                    return input.getId();
                }
            });
            List<SupportWithMember> distribSupportList = supportService.findByRelationId(distributorCount.getDistributorRalationId());
            List<String> distSuppIds = LangUtils.transform(distribSupportList, new Function<Support, String>() {
                @Nullable
                @Override
                public String apply(@Nullable Support input) {
                    return input.getId();
                }
            });
            crowdSuppIds.removeAll(distSuppIds);

            for (String supportId : crowdSuppIds) {
                Support support = supportService.get(supportId);
                DistributorDetail distributorDetail = distributorDetailService.get(support.getOrderId(),
                        DistributorDetailType.DISTRIBUTOR_TYPE_SUPPORT.getCode(),
                        distributorCount.getDistributorRalationId());
                if (null != distributorDetail) {
                    continue;
                }
                distributorDetail = new DistributorDetail();
                distributorDetail.setTargetId(support.getOrderId());
                distributorDetail.setDistributorRelationId(distributorCount.getDistributorRalationId());
                distributorDetail.setCreateDate(support.getCreateDate());
                distributorDetail.setUpdateDate(support.getUpdateDate());
                distributorDetail.setType(DistributorDetailType.DISTRIBUTOR_TYPE_SUPPORT.getCode());
                distributorDetailService.insert(distributorDetail);
            }

            if (DistributorRelationType.CROWDFUND_REPRESENT.getCode().equals(distributionType)) {
                Integer favorerNum = 0;
                Float favorerAmount = 0f;
                //矫正统计数据
                for (ProjectWithAuthor projectWithAuthor1 : projectWithAuthorList) {
                    favorerNum = favorerNum + projectWithAuthor1.getFavorerNum();
                    favorerAmount = BigDecimalUtils.add(favorerAmount, projectWithAuthor1.getActualAmount());
                    favorerAmount = BigDecimalUtils.round(favorerAmount, 2);
                }
                distributorCount.setFavorerNum(favorerNum);
                distributorCount.setFavorerAmount(favorerAmount);
            }

            if (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributionType)) {
                Float favorerAmount = 0f;
                //矫正统计数据
                for (SupportWithMember support : crowdSupportList) {
                    favorerAmount = BigDecimalUtils.add(favorerAmount, support.getPayment());
                    favorerAmount = BigDecimalUtils.round(favorerAmount, 2);
                }
                distributorCount.setFavorerNum(crowdSupportList.size());
                distributorCount.setFavorerAmount(favorerAmount);
            }

            ProjectWithAuthor projectWithAuthor1 = new ProjectWithAuthor();
            projectWithAuthor1.setRelationId(distributorCount.getDistributorRalationId());
            projectWithAuthor1.setIsSuccess(1);
            List<ProjectWithAuthor> projectWithAuthorList2 = projectService.listPage(projectWithAuthor1, null);
            distributorCount.setSuccessNum(projectWithAuthorList2.size());
        } else {
            distributorCount.setFavorerNum(0);
            distributorCount.setFavorerAmount(0f);
        }
    }
}
